package boot

import (
	"context"
	"github.com/gogf/gf/contrib/config/nacos/v2"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
)

// initNacos initializes the Nacos configuration.
func InitNacos(namespace string, group string, dataId string) {
	ctx := gctx.GetInitCtx()

	// Load Nacos configuration from environment variables with default values
	//nacosEnable := getEnvOrDefault(ctx, "NACOS_ENABLE", false).Bool()
	//if !nacosEnable {
	//	g.Log().Info(ctx, "Nacos integration is disabled. Skipping initialization.")
	//	return
	//}

	serverAddr := getEnvOrDefault(ctx, "NACOS_SERVER_ADDR", "127.0.0.1").String()
	serverPort := getEnvOrDefault(ctx, "NACOS_SERVER_PORT", 8848).Int()
	cacheDir := getEnvOrDefault(ctx, "NACOS_CLIENT_CACHEDIR", "./cache/nacos").String()
	logDir := getEnvOrDefault(ctx, "NACOS_CLIENT_LOGDIR", "./logs/nacos").String()
	logLevel := getEnvOrDefault(ctx, "NACOS_CLIENT_LOGLEVEL", "info").String()
	username := getEnvOrDefault(ctx, "NACOS_USERNAME", "").String()
	password := getEnvOrDefault(ctx, "NACOS_PASSWORD", "").String()
	//namespace := getEnvOrDefault(ctx, "NACOS_NAMESPACE", "public").String()
	//dataId := getEnvOrDefault(ctx, "NACOS_DATAID", "portal.config").String()
	//appName := getEnvOrDefault(ctx, "APP_NAME", "").String()
	//group := getEnvOrDefault(ctx, "NACOS_GROUP", "DEFAULT_GROUP").String()
	// Validate the server port
	if serverPort <= 0 || serverPort > 65535 {
		g.Log().Fatalf(ctx, "Invalid NACOS_SERVER_PORT value: %d. Must be between 1 and 65535.", serverPort)
	}
	//if appName == "" {
	//	g.Log().Errorf(ctx, "Invalid NACOS_CONFIG APP_NAME is not set.")
	//	return
	//}
	//dataId := fmt.Sprintf("%s.config", appName)

	// Log the configuration details
	g.Log().Infof(ctx, "Initializing Nacos with: serverAddr=%s, namespace=%s, dataId=%s, group=%s ,username=%s,password=%s", serverAddr, namespace, dataId, group, username, password)
	// Create server and client configurations
	serverConfig := constant.ServerConfig{
		IpAddr: serverAddr,
		Port:   uint64(serverPort),
	}
	clientConfig := constant.ClientConfig{
		NamespaceId: namespace,
		Username:    username,
		Password:    password,
		CacheDir:    cacheDir,
		LogDir:      logDir,
		LogLevel:    logLevel,
	}
	configParam := vo.ConfigParam{
		DataId: dataId,
		Group:  group,
	}

	// Initialize the Nacos adapter
	adapter, err := nacos.New(ctx, nacos.Config{
		ServerConfigs: []constant.ServerConfig{serverConfig},
		ClientConfig:  clientConfig,
		ConfigParam:   configParam,
	})
	if err != nil {
		g.Log().Errorf(ctx, "Failed to initialize nacos adapter: %v", err)
		return
	}
	// Fetch configuration data from Nacos
	configData, err := adapter.Data(ctx)
	if err != nil {
		g.Log().Errorf(ctx, "Failed to fetch nacos configuration data from Nacos: %v", err)
		return
	}

	if configData == nil {
		g.Log().Error(ctx, "Nacos configuration data is nil.")
		return
	}

	// Set the global configuration adapter
	g.Cfg().SetAdapter(adapter)
	// Log successful initialization
	g.Log().Info(ctx, "Nacos configuration successfully initialized.")
}

// getEnvOrDefault retrieves an environment variable or returns a default value if not set or empty.
func getEnvOrDefault(ctx context.Context, key string, defaultValue interface{}) *g.Var {
	value, err := g.Cfg().GetWithEnv(ctx, key)
	g.Log().Infof(ctx, "Environment variable %s: %v", key, value)
	if err != nil || value == nil || value.IsEmpty() {
		return g.NewVar(defaultValue) // Use g.NewVar to create a new variable with the default value
	}
	return value
}
